home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
edit
/
me_cd25.zip
/
MUTT2.ZIP
/
GOMOKU.MUT
< prev
next >
Wrap
Lisp/Scheme
|
1992-11-09
|
44KB
|
1,347 lines
;; Once installed and compiled, the program is invoked with 'M-x gomoku'
;; and 'C-h m' (the well-known describe-mode) will list all key bindings
;; provided to the player. Have fun.
;;; Gomoku game between you and GNU Emacs. Last modified on 13 Sep 1988
;;; Converted to Mutt 9/88 C Durland
;;;
;;; Written by Ph. Schnoebelen (phs@lifia.imag.fr), 1987, 1988
;;; with precious advices from J.-F. Rit.
;;; This has been tested with GNU Emacs 18.50.
;;;
;;; This software is distributed 'as is', without warranties of any
;;; kind, but all comments, suggestions and bug reports are welcome.
;; RULES:
;;
;; Gomoku is a game played between two players on a rectangular board. Each
;; player, in turn, marks a free square of its choice. The winner is the first
;; one to mark five contiguous squares in any direction (horizontally,
;; vertically or diagonally).
;;
;; I have been told that, in "The TRUE Gomoku", some restrictions are made
;; about the squares where one may play, or else there is a known forced win
;; for the first player. This program has no such restriction, but it does not
;; know about the forced win, nor do I. Furthermore, you probably do not know
;; it yourself :-).
;; HOW TO INSTALL:
;;
;; There is nothing specific w.r.t. installation: just put this file in the
;; lisp directory and add an autoload for command gomoku in site-init.el. If
;; you don't want to rebuild Emacs, then every single user interested in
;; Gomoku will have to put the autoload command in its .emacs file. Another
;; possibility is to define in your .emacs some command using (require
;; 'gomoku).
;;
;; The most important thing is to BYTE-COMPILE gomoku.el because it is
;; important that the code be as fast as possible.
;;
;; There are two main places where you may want to customize the program: key
;; bindings and board display. These features are commented in the code. Go
;; and see.
;; HOW TO USE:
;;
;; Once this file has been installed, the command "M-x gomoku" will display a
;; board, the size of which depends on the size of the current window. The
;; size of the board is easily modified by giving numeric arguments to the
;; gomoku command and/or by customizing the displaying parameters.
;;
;; Emacs plays when it is its turn. When it is your turn, just put the cursor
;; on the square where you want to play and hit RET, or X, or whatever key you
;; bind to the command gomoku-human-plays. When it is your turn, Emacs is
;; idle: you may switch buffers, read your mail, ... Just come back to the
;; *Gomoku* buffer and resume play.
;; ALGORITHM:
;;
;; The algorithm is briefly described in section "THE SCORE TABLE". Some
;; parameters may be modified if you want to change the style exhibited by the
;; program.
(include me2.h)
(include mod.mut)
(include random.mut)
(include max.mut)
(include min.mut)
;;;
;;; GOMOKU MODE AND KEYMAP.
;;;
(include nomunge.mut)
(defun create-gomoku-mode-map
{
(buffer-nomunge)
;; Key bindings for cursor motion. Arrow keys are just "function"
;; keys, see below.
(bind-local-key "gomoku-move-nw" "y") ; Y
(bind-local-key "gomoku-move-ne" "u") ; U
(bind-local-key "gomoku-move-sw" "b") ; B
(bind-local-key "gomoku-move-se" "n") ; N
(bind-local-key "gomoku-move-left" "h") ; H
(bind-local-key "gomoku-move-right" "l") ; L
(bind-local-key "gomoku-move-down" "j") ; J
(bind-local-key "gomoku-move-up" "k") ; K
(bind-local-key "gomoku-move-down" "C-n") ; C-N
(bind-local-key "gomoku-move-down" "F-D") ; down arrow
(bind-local-key "gomoku-move-up" "C-p") ; C-P
(bind-local-key "gomoku-move-up" "F-C") ; up arrow
(bind-local-key "gomoku-move-right" "C-f") ; C-F
(bind-local-key "gomoku-move-right" "F-E") ; right arrow
(bind-local-key "gomoku-move-left" "C-b") ; C-B
(bind-local-key "gomoku-move-left" "F-F") ; left arrow
;; Key bindings for entering Human moves.
(bind-local-key "gomoku-human-plays" "X") ; X
(bind-local-key "gomoku-human-plays" "x") ; x
(bind-local-key "gomoku-human-plays" "C-m") ; RET
; (bind-local-key "gomoku-human-plays" "C-Xp") ; C-C P
(bind-local-key "gomoku-human-resigns" "C-Xr") ; C-C R
(bind-local-key "gomoku-emacs-plays" "C-Xe") ; C-C E
; (bind-local-key "gomoku-human-takes-back" "C-cb") ; C-C B
})
;; Major mode for playing Gomoku against Emacs. You and Emacs play in
;; turn by marking a free square. You mark it with X and Emacs marks it
;; with O. The winner is the first to get five contiguous marks
;; horizontally, vertically or in diagonal. You play by moving the cursor
;; over the square you choose and hitting RET, x, .. or whatever has been
;; set locally.
;; Other useful commands:
;; C-c r Indicate that you resign.
;; C-c t Take back your last move.
;; C-c e Ask for Emacs to play (thus passing).
(defun gomoku-mode
{
; (setq major-mode 'gomoku-mode mode-name "Gomoku")
(clear-modes)
(major-mode "Gomoku")
(gomoku-display-statistics)
(create-gomoku-mode-map)
})
;;;
;;; THE BOARD.
;;;
;; The board is a rectangular grid. We code empty squares with 0, X's
;; with 1 and O's with 6. The rectangle is recorded in a one dimensional
;; vector containing padding squares (coded with -1). These squares allow
;; us to detect when we are trying to move out of the board. We denote a
;; square by its (X,Y) coords, or by the INDEX corresponding to them in the
;; vector. The leftmost topmost square has coords (1,1) and index
;; gomoku-board-width + 2. Similarly, vectors between squares may be given
;; by two DX, DY coords or by one DEPL (the difference between indexes).
(const gomoku-max-vector-length 4000)
;; Number of columns on the Gomoku board.
(int gomoku-board-width)
;; Number of lines on the Gomoku board.
(int gomoku-board-height)
;; Vector recording the actual state of the Gomoku board.
(array int gomoku-board gomoku-max-vector-length)
;; Length of gomoku-board vector.
(int gomoku-vector-length)
;; After how many moves will Emacs offer a draw ?
;; This is usually set to 70% of the number of squares.
(int gomoku-draw-limit)
;; Translate X, Y cartesian coords into the corresponding board index.
(defun gomoku-xy-to-index (int x y) { (+ (* y gomoku-board-width) x y) })
;; Return corresponding x-coord of board INDEX.
(defun gomoku-index-to-x (int index) { (mod index (+ 1 gomoku-board-width)) })
;; Return corresponding y-coord of board INDEX.
(defun gomoku-index-to-y (int index) { (/ index (+ 1 gomoku-board-width)) })
;; Create the gomoku-board vector and fill it with initial values.
(defun gomoku-init-board
{
(int i ii)
;(setq gomoku-board (make-vector gomoku-vector-length 0))
;; Every square is 0 (i.e. empty) except padding squares:
(i gomoku-vector-length) (while (!= 0 (-= i 1)) (gomoku-board i 0))
(i 0) (ii (- gomoku-vector-length 1))
(while (<= i gomoku-board-width) ; The squares in [0..width] and in
{
(gomoku-board i -1) ; [length - width - 1..length - 1]
(gomoku-board ii -1) ; are padding squares.
(+= i 1)(-= ii 1)
})
(i 0)
(while (< i gomoku-vector-length)
{
(gomoku-board i -1) ; and also all k*(width+1)
(+= i gomoku-board-width 1)
})
})
;;;
;;; THE SCORE TABLE.
;;;
;; Every (free) square has a score associated to it, recorded in the
;; GOMOKU-SCORE-TABLE vector. The program always plays in the square having
;; the highest score.
;; Vector recording the actual score of the free squares.
(array int gomoku-score-table gomoku-max-vector-length)
;; The key point about the algorithm is that, rather than considering
;; the board as just a set of squares, we prefer to see it as a "space" of
;; internested 5-tuples of contiguous squares (called qtuples).
;;
;; The aim of the program is to fill one qtuple with its O's while preventing
;; you from filling another one with your X's. To that effect, it computes a
;; score for every qtuple, with better qtuples having better scores. Of
;; course, the score of a